/*
基于jquery的html编辑器排版控件

onClose(operation,code) layout弹出框关闭后回调函数。

operation："cancel"、"insert"或者"set"
"cancel"表示用户点击了“取消”按钮
"insert"表示用户点击了“确定”按钮，并且设计器中布局是新建的。
"set"表示用户点击了“确定”按钮，并且设计器中布局是从html编辑器代码中加载的。
  
code:layout布局代码
*/
function Layout(onClose)
{
    var width = getBodyWidth();
    var height = getBodyHeight();
    
    var fun = onClose;

    var dg = new Drag("l_pcon");

    var MW = 20;//最小宽度
    var MH = 20;//最小高度

    var cw = width;
    var ch = height-25;
    var reg = new RegExp(/^\d+$/);
    
    var INFO = null; //info方法返回值
    
    //load方法用
    var code = null;
    var rs = null;
    var ls = null;
    var lb = null;

    var tp = new TabPanel(width,height,"设计=200,预览=200,说明=200");
    $("body").append(tp.getObj());
    
    var d = $("<div><div var id='l_pcon' style='width:"+(width-210)+"px;height:"+ch+"px;float:left;overflow:scroll;'></div><div style='width:210px;height:"+ch+"px;background-color:#f5f5f5;float:left;'></div></div>");
    tp.get("设计").append(d);
    
    //var tb0 = new ToolBar(10,8,"sp=54,bt新建布局=116");
    var tb0 = new ToolBar(10,8,"st布局：=56,bt新建布局=114");
    
    var tb1 = new ToolBar(10,8,"st行高：=56,it=40,bt添加行=64");
    var tb10 = new ToolBar(10,8,"sp=106,bt插入行=64");
    var tb2 = new ToolBar(10,8,"st列宽：=56,it=40,bt添加列=64");
    var tb20 = new ToolBar(10,8,"sp=106,bt插入列=64");
    var tb3 = new ToolBar(10,8,"st宽度：=56,it=40,bt-=30,bt+=30");
    var tb4 = new ToolBar(10,8,"st高度：=56,it=40,bt-=30,bt+=30");
    var tb5 = new ToolBar(10,8,"st内边距：=56,it=40,bt-=30,bt+=30");
    
    var tb6 = new ToolBar(10,2,"sp=56,bt移除单元格=114");
    var tb7 = new ToolBar(10,10,"sp=38,bt确定=64,bt取消=64");
    
    var tb8 = new ToolBar(10,2,"sp=56,bt返回上一层↑=114");
    
    
    var help = new Array();
    help.push("<div style='font-size:14px;line-height:24px;margin:20px;color:#cc3333;'>");
    help.push("<span style='font-weight:bold;'>设计器：</span><br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;父容器中可以添加行或者列。<br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;父容器的宽度、高度可调整。<br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;单元格如果属性为行，其内部只可以再添加列。属性是列，其内部只能再添加行。<br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;属性为行的单元格高度可以调整。属性为列的单元格宽度可以调整。（不能溢出父单元格或容器）<br/>");
    help.push("<span style='color:#fff;'>■</span>&nbsp;&nbsp;调整宽度和高度时，如果在编辑框输入较大或较小数值，然后点击+或-按钮，则直接设为该值。<br/><br/>");
 
    help.push("<span style='font-weight:bold;'>生成代码：</span><br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;父容器、单元格的宽度固定，高度在设计器指定值基础上可随内容自增。<br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;如果html编辑器中已有布局，会默认载入。如想在编辑器光标处插入新布局，请在设计器中新建布局。<br/>");
    help.push("<span style='color:#666;'>■</span>&nbsp;&nbsp;建议单个网页中放置一个布局，支持前后放置多个布局。不支持布局嵌套。<br/>");
    help.push("</div>");
    
    tp.get("说明").append(help.join(""));
    
    
    
    
    var cls = new Colors(10,10,function(c){
      LS().border(c);
    });
    
    d.children().eq(1).append(tb0.getObj());
    d.children().eq(1).append(tb6.getObj());
    d.children().eq(1).append(tb8.getObj());
    
    d.children().eq(1).append(tb1.getObj());
    d.children().eq(1).append(tb10.getObj());
    d.children().eq(1).append(tb2.getObj());
    d.children().eq(1).append(tb20.getObj());
    d.children().eq(1).append(tb3.getObj());
    d.children().eq(1).append(tb4.getObj());
    d.children().eq(1).append(tb5.getObj());

    d.children().eq(1).append(cls.getObj());
    
    d.children().eq(1).append(tb7.getObj());
    
    
   tb0.setClick(function(t){
      switch(t){
      case "新建布局":
        code = null;
        rs = null;
        ls = null;
        lb = null;
        dg.clear();
        ls0 = new Layout_shown(800,400,null,dg);
        ls0.select(onSel);
        INFO = ls0.selObj(null);
        d.children().eq(0).empty();
        d.children().eq(0).append(ls0.getObj());
      break;
      }
    });
    

   tb7.setClick(function(t){
      switch(t){
      case "取消":
        if(OK(fun)){
          dg.clear();
          tp.getObj().remove();
          fun("cancel",_get(0));
        }
      break;
      case "确定":
        if(OK(fun)){
          dg.clear();
          tp.getObj().remove();
          fun((rs != null && rs.length > 0) ? "set" : "insert",_get(0));
        }
      break;
      }
    });
    
   tb8.setClick(function(t){
      switch(t){
      case "返回上一层↑":
      LS().up();  
      break;
      }
    });
    
    //初始设计对象
    var ls0 = new Layout_shown(800,400,null,dg);
    ls0.select(onSel);
    INFO = ls0.selObj(null);
    d.children().eq(0).append(ls0.getObj());
    
    
    this.getObj = function()
    {
       return tp.getObj();
    }
    
    var SID = null;
    function LS(id)
    {
      if(OK(id)){
        if(rs != null && rs.length > 0){
          for(var i=0;i<ls.length;++i){
            if(same(ls[i].ID(),id)){
              return ls[i];
            }
          }
        }
        else{
          return null;
        }
      }
      else{
        if(rs != null && rs.length > 0){
          for(var i=0;i<ls.length;++i){
            if(same(ls[i].ID(),SID)){
              return ls[i];
            }
          }
        }
        else{
          return ls0;
        }
      }
    }
    
    //用户未指定数值情况下默认宽度
    function get_w(max)
    {
      if(max >= 200){
        return 200;
      }
      else if(max >= 100){
        return 100;
      }
      else if(max >= 50){
        return 50;
      }
      else{
        return MW;
      }
    }
    
    //用户未指定数值情况下默认高度
    function get_h(max)
    {
      if(max >= 200){
        return 200;
      }
      else if(max >= 100){
        return 100;
      }
      else if(max >= 50){
        return 50;
      }
      else{
        return MH;
      }
    }
    
    tb1.setClick(function(t){
      switch(t){
      case "添加行":
      
      var max = INFO.rh;
      
      var ht = tb1.text(1);
      var h = get_h(max);
      
      if(OK(ht)){
        if(!reg.test(ht)){
          alert("请输入数值");
          return;
        }
        else{
          h = parseInt(ht);
          
          if(max < MH){
            alert("剩余空间不足!");
            return;
          }
          else if(h < MH ||  h > max){
            alert("行高值应在"+MH+" - "+max+"之间");
            return;
          }
        }
      }
      
      LS().addRow(h);
      INFO = LS().getInfo(null);
      
      break;
      }
    });
    
    tb10.setClick(function(t){
      switch(t){
      case "插入行":
      
      var max = INFO.mh - INFO.height;
      
      var ht = tb1.text(1);
      var h = get_h(max);
      
      if(OK(ht)){
        if(!reg.test(ht)){
          alert("请输入数值");
          return;
        }
        else{
          h = parseInt(ht);
          
          if(max < MH){
            alert("剩余空间不足!");
            return;
          }
          if(h < MH ||  h > max){
            alert("行高值应在"+MH+" - "+max+"之间");
            return;
          }
        }
      }
      
      LS().insertRow(h);
      INFO = LS().getInfo(null);
      
      break;
      }
    });
    
    tb2.setClick(function(t){
      switch(t){
      case "添加列":
      var max = INFO.rw;
   
      var w = get_w(max);
      
      var wt = tb2.text(1);
      
      if(OK(wt)){
        if(!reg.test(wt)){
          alert("请输入数值");
          return;
        }
        else{
          w = parseInt(wt);
          
          if(max < MW){
            alert("剩余空间不足!");
            return;
          }
          else if(w < MW ||  w > max){
            alert("列宽值应在"+MW+" - "+max+"之间");
            return;
          }
        }
      }
      LS().addCol(w);
      INFO = LS().getInfo(null);
      break;
      }
    });
    
    tb20.setClick(function(t){
      switch(t){
      case "插入列":
      var max = INFO.mw - INFO.width;
   
      var w = get_w(max);
      
      var wt = tb2.text(1);
      
      if(OK(wt)){
        if(!reg.test(wt)){
          alert("请输入数值");
          return;
        }
        else{
          w = parseInt(wt);
          
          if(max < MW){
            alert("剩余空间不足!");
            return;
          }
          else if(w < MW ||  w > max){
            alert("列宽值应在"+MW+" - "+max+"之间");
            return;
          }
        }
      }
      LS().insertCol(w);
      INFO = LS().getInfo(null);
      break;
      }
    });
    
    tb3.setClick(function(t){
    
      var _ls = LS();
      var _info = _ls.getInfo();
      
      var w = _info.width;
      
      var w0 = -1;
      var tw = tb3.text(1);
      if(reg.test(tw)){
        w0 = parseInt(tw);
      }
      //加减号除了逐一递增、递减外，也可直接设定一数值
      switch(t){
        case "+":
        if(w0 > w && w0 > 0){w = w0;}else{w++;}
        break;
        
        case "-":
        if(w0 < w && w0 > 0){w = w0;}else{w--;}
        break;
      }
      
      if(w < MW){alert("最小宽度值："+MW);return;}
      
      if(_info.root && w < _info.ws){alert("宽度值不能小于"+_info.ws+"，如需改变请先调整内部单元格尺寸。");return;}
      
      if(w > _info.mw){
        alert("宽度值不能大于" +_info.mw);
        return;
      }

      _ls.setWidth(w);
    });
    
    tb4.setClick(function(t){
      var _ls = LS();
      var _info = _ls.getInfo();
      var h = parseInt(_info.height);
      
      var h0 = -1;
      var th = tb4.text(1);
      if(reg.test(th)){
        h0 = parseInt(th);
      }

      switch(t){
        case "+":
        if(h0 > h && h0 > 0){h = h0;}else{h++};
        break;
        
        case "-":
        if(h0 < h && h0 > 0){h = h0;}else{h--};
        break;
      }
      
      if(h < MH){alert("最小高度值："+MH);return;}
      
      if(_info.root && h < _info.hs){alert("高度值不能小于"+_info.hs+"，如需改变请先调整内部单元格尺寸。");return;}
      
      if(h > _info.mh){
        alert("高度值不能大于" +_info.mh);
        return;
      }

      _ls.setHeight(h);
    });
    
    tb5.setClick(function(t){
      var _ls = LS();
      var _info = _ls.getInfo();
      var p = parseInt(_info.padding);
    
      switch(t){
        case "+":
        p++;
        break;
        
        case "-":
        p--;
        break;
      }
      
      if((p < 0) ||  p > 20){
        alert("值应在0 - 20之间");
        return;
      }
      _ls.setPadding(p);
    });
    
    tb6.setClick(function(t){
      switch(t){
      case "移除单元格":
      if(confirm("您确定要移除当前项吗？")){
        LS().del();
      }
      break;
      }
    });
    
    
    var _lastHtml = null;//上一次转换而成的预览代码
    
    tp.setSel(function(t){
      switch(t){
        case "设计":
        
        break;
        case "预览":
        var html = _get(1);
        if(html != _lastHtml){
          tp.get("预览").empty();
          tp.get("预览").append("<div style='width:"+cw+"px;height:"+ch+"px;overflow:scroll;'><div style='margin-top:10px;margin-left:10px;'>"+html+"</div></div>");
          _lastHtml = html;
        }

        break;
        case "说明":
        //ft[0].value = _get(0);
        break;
      }
    });
    
    var _s = 0;
    
    dg.setDrag(
    function(id,border){
      var ls = LS();
      ls.lockObj(true);
      
      if(border == 1){
        _s = ls.getInfo().width;
      }
      else if(border == 2){
        _s = ls.getInfo().height;
      }
    },
    function(id,border,size,offset){
      
      if(border == 1){
        var _ls = LS();
        var _info = _ls.getInfo();
        
        var w = _s + offset;

        if(w >= MW &&  w <= _info.mw){
          _ls.setWidth(w);
        } 
      }
      else if(border == 2){
        var _ls = LS();
        var _info = _ls.getInfo();
        
        var h = _s + offset;

        if(h >= MH &&  h <= _info.mh){
          _ls.setHeight(h);
        }
      }
      return false;
    },
    function(id,border){
      //LS().lockObj(false);
    });
    

   
   /*
      从html源码中提取Layout
   */
   function _load(source)
   {
      code = source;
      lb = new Layout_Buffer(code);
      
      rs = getHtml(code,"div","class","l_con");
      
      if(rs.length > 0){
        dg.clear();
        d.children().eq(0).empty();
        
      
        ls = new Array(rs.length);
        
        for(var i=0;i<rs.length;++i){
        
          var ls0 = new Layout_shown(rs[i].width,rs[i].height,rs[i].id,dg);
          d.children().eq(0).append(ls0.getObj());
          
          ls[i] = ls0;
          ls0.select(onSel);
          ls0.border(rs[i].border);
          if(OK(rs[i].click)){
            ls0.click(rs[i].click);
          }
          
          if(i==0){INFO = ls0.selObj(null);}
           
          
          var jq = $(rs[i].header+rs[i].html+"</div>");
          fromTable(ls0,jq);
          
          
          if(i > 0){
            ls0.getObj().css("margin-top","50px");
          }
          else{
            ls0.getObj().css("margin-top","8px");
          }
          
          //d.children().eq(0).append(ls0.getObj());
        }
      }
   }
   
   this.load = function(source)
   {
      _load(source);
   }
   
   //flag = 0表示获取完整代码,flag = 1表示获取设计器状态代码
   //两者不同之处是对边框为#fff的表现以及用户代码的表现
   function _get(flag)
   {
      if(rs != null && rs.length > 0){
        var re = code;
        
        for(var i=0;i<rs.length;++i){
          var s = rs[i].header + rs[i].html + "</div>";
          var t = ls[i].get(lb,flag);
          var re0 = re;
          re = new strReplace("sc").replace(re,s,t);
          //if(flag == 0){debug(re0,s,t,re);}
        }

        return re;
      }
      else{
        return ls0.get(null,flag);
      }
   }
   
   //获取布局代码
   this.get = function()
   {
      return _get(0);
   }

   function onSel(info){

      if(OK(info)){
        if(OK(SID) && !same(SID,info.id)){
          var last = LS(SID);
          if(OK(last)){last.cancelSel();}
        }
      
      
        INFO = info;
        SID = info.id;
        tb5.enable(2,true);  tb5.enable(3,true);
        
        tb5.text(1,info.padding + "");
        tb6.enable(1,true);
      
        var child = info.child;
        
        if(child == 0){
          if(info.root){
            tb1.enable(2,true);
            tb2.enable(2,true);
          }
          else{
            if(same(info.type,"tb")){
              tb1.enable(2,false);
              tb2.enable(2,true);
            }
            else if(same(info.type,"td")){
              tb1.enable(2,true);
              tb2.enable(2,false);
            }
          }
        }
        else{
          tb1.enable(2,child == 2 ? false : true);
          tb2.enable(2,child == 1 ? false : true);
          
          tb5.enable(2,false);  tb5.enable(3,false);
        }

        var w = info.width + "";
        var h = info.height + "";
        
        tb3.enable(2,false); tb3.enable(3,false);
        tb4.enable(2,false); tb4.enable(3,false);
        
        if(same(info.type,"tb")){
          tb4.text(1,h);
          
          tb4.enable(2,true); tb4.enable(3,true);
          
          tb3.text(1,w);
        }
        
        if(same(info.type,"td") || info.root){
          tb3.text(1,w);
          tb3.enable(2,true); tb3.enable(3,true);
          
          if(!info.root){
            tb4.text(1,h);
          }
        }
        
        if(info.root){
          tb6.enable(1,false);
        }
        else{
          tb6.enable(1,true);
        }
        
        //插入行、插入列
        tb10.enable(1,false);
        tb20.enable(1,false);
        
        if(!info.root){
          if(same(info.type,"td")){
            if(info.mw - info.width >= MW){
              tb20.enable(1,true);
            }
          }
          else if(same(info.type,"tb")){
            if(info.mh - info.height >= MH){
              tb10.enable(1,true);
            }
          }
        }

        cls.set(LS().border());
      }
      else{
        tb1.enable(2,false);
        tb2.enable(2,false);
        tb3.enable(2,false);  tb3.enable(3,false);
        tb4.enable(2,false);  tb4.enable(3,false);
        tb5.enable(2,false);  tb5.enable(3,false);
        tb6.enable(2,false);
        
        tb3.text(1,"");
        tb4.text(1,"");
        
        cls.set("#fff");
      }
   }
   
}


//实际对象转设计器对象
//ls是Layout_shown对象,pa是父容器(最外层div或一个td,内含一个table)
function fromTable(ls,pa)
{
  if(pa.children().length == 0){
    return;
  }

  var PID = pa.prop("id");

  var tb = pa.children().eq(0);
  
  if(same(tb.prop("class"),"l_tb")){
    var trs = tb.children("tbody").children("tr");
    
    if(trs.length > 1){//多行一列
      trs.each(function(){
        var td = $(this).children("td").eq(0);
        var _h = td.attr("_h");
        var _p = td.attr("_p");
        var ID = td.prop("id");
        
        ls.selObj(PID);
        ls.addRow(parseInt(_h),ID);
        
        if(parseInt(_p) > 0){
          ls.selObj(ID);
          ls.setPadding(_p);
        }

        fromTable(ls,td);
      });
    }
    else if(trs.length == 1){//一行多列
      var tds = trs.eq(0).children("td");
      
      if(tds.length > 1){//如果只有一列，说明布局只有一个父容器
        tds.each(function(){
          var td = $(this);
          var _w = td.attr("_w");
          var _p = td.attr("_p");
          var ID = td.prop("id");
          
          ls.selObj(PID);
          ls.addCol(parseInt(_w),ID);
          
          if(parseInt(_p) > 0){
            ls.selObj(ID);
            ls.setPadding(_p);
          }

          fromTable(ls,td);
        });
      }
    }
  }
}


//获取排版中包含的用户代码
function Layout_Buffer(code)
{
  //code=n的td是最内层td，可能包含用户代码
  var rs = getHtml(code,"td","code","n");
  
  this.get = function(id)
  {
    for(var i=0;i<rs.length;++i){
      if(same(rs[i].id,id)){
        return OK(rs[i].html) ? rs[i].html : "";
      }
    }
    return "";
  }
}


/* 
 排版工具
 依赖：jquery
 用途：html编辑器
 原理：利用table进行排版,table可以嵌套，单个table只能是一行多列或多行一列。
 
 dg是Drag对象
*/

function Layout_shown(Width,Height,ID,drag)
{
  var dg = drag;

  var MW = 20;//最小宽度
  var MH = 20;//最小高度
  
  var ROOT = OK(ID) ? ID : ("root_"+randomString(8));

  var sel = null;//当前选择项
  var onSel = null;//回调函数
  var _border = "#fff";//边框颜色
  var _click = null;//td的回调方法名称


  var obj = $("<div id='"+ROOT+"' type='tb' _w='"+Width+"' _h='"+Height+"' _p='0' style='width:"+Width+
              "px;height:"+Height+"px;margin-left:auto;margin-right:auto;margin-top:8px;margin-bottom:8px;overflow-x:hidden;background-color:#fff;border:#888 dotted 1px;'></div>");

  if(OK(dg)){dg.add(ROOT,3);}

  obj.click(function(){
    if(_lock){_lock = false; return;}
  
    if(OK(sel)){
      if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      sel.css("background-color","#fff");
    }
  
    sel = $(this);
    sel.css("background-color","#E6EFFA");
    if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
    
    if(OK(onSel)){
      onSel(info(sel));
    }
  });
   
  
  this.getObj = function()
  {
    return obj;
  }
  
  this.ID = function()
  {
    return ROOT;
  }
  
  //取消选择，不触发事件
  this.cancelSel = function()
  {
    if(OK(sel)){
      sel.css("background-color","#fff");
      if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
    }
  
    sel = null;
  }
  
  function _selObj(id)
  {
    var INFO = null;
    var o = ((id == null || same(id,ROOT))? obj : obj.find("#"+id));
  
    if(o != null){
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = o;
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        INFO = info(sel);
        onSel(INFO);
      }
      return INFO;
    }
    else if(o == null){
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = obj;
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        INFO = info(sel);
        onSel(INFO);
      }
      return INFO;
    }
    else{
      return sel;
    }
  }
  
  //ud为空表示选中最外层容器
  this.selObj = function(id)
  {
    return _selObj(id);
  }
  
  //选择父容器
  this.up = function()
  {
    if(!same(sel.prop("id"),ROOT)){
      _selObj(sel.parent().prop("id"));
    }
  }
  
  //锁定选择对象不可改更
  var _lock = false;
  this.lockObj = function(b){
    _lock = b;
  }

  
  //指定边框颜色，比如 #bbb
  this.border = function(bd)
  {
    if(OK(bd)){
      _border = bd;
    }
    else{
      return _border;
    }
  }
  
  //是否启用td click回调函数，该函数位于包含html编辑器的网页代码中
  //该函数的参数是当前TD的宽度和高度以及padding
  this.click = function(i)
  {
    if(OK(i)){
      _click = (i > 0 ? "layout_click" : null);
    }
    else{
      return _click;
    }
  }
  
  //设置单元响应函数
  this.select = function(fun)
  {
    onSel = fun;
  }
  

  
  //调整设计对象，补齐剩余宽度、高度
  function adjust(o)
  {
    o.children().each(function(){
      adjust($(this));
    });
  
    var f = info(o);
    
    if(f.child == 1){//补齐高度
    
      if(f.rh > MH){

        var ID = "td_"+randomString(8);
        var n = $("<div id='"+ID+"' type='tb' _h='"+f.rh+"' _w='0' ></div>");
        o.append(n);
      }
    }
    else if(f.child == 2){//补齐宽度
      
      if(f.rw > MW){
        var ID = "td_"+randomString(8);
        var n = $("<div id='"+ID+"' type='td' _h='0' _w='"+f.rw+"' ></div>");
        o.append(n);
      }
    }
  }
  
  
  //判断单元格o的尺寸是否受边框影响
  function borderCheck(o)
  {
    var right = false;
    var bottom = false;
  
    var p = o;
    
    while(!same(p.prop("id"),ROOT)){

      var b = haveBorder(p);
      
      if( b == 1){
        right = true;
      }
      
      if(b == 2){
        bottom = true;
      }
      
      p = p.parent();
    }
    return {"right":right,"bottom":bottom};
  }
  
  //判断单元格o尺寸是否受边框影响。返回值0：无边框，1：受右边框影响，2：受下边框影响
  //https://bbs.csdn.net/topics/392452605
  function haveBorder(o)
  {
    var index = o.prevAll().length;
    var L = o.parent().children().length;
    
    if(OK(_border) && L > 1 && index != L - 1)//边框会占据1个像素宽度，所以要对子元素尺寸进行修正
    {
      if(same(o.attr("type"),"td")){
        return 1;
      }
      else if(same(o.attr("type"),"tb")){
        return 2;
      }
    }
    
    return 0;
  }
  
  
  //获取父容器宽
  function _width(o){
  
    if(same(o.prop("id"),ROOT)){
      return parseInt(o.attr("_w"));
    }

    var q = o.parent();
    var w = q.attr("_w");
    
    if(!OK(w) || w=="0"){
      q = q.parent();
      w = q.attr("_w");
    }
    
    return parseInt(w);
  }
  
  ////获取父容器高
  function _height(o)
  {
    if(same(o.prop("id"),ROOT)){
      return parseInt(o.attr("_h"));
    }
    

    var q = o.parent();
    var h = q.attr("_h");
    
    if(!OK(h) || h=="0"){
      q = q.parent();
      h = q.attr("_h");
    }
    
    return parseInt(h);
  }
  
  this.getInfo = function(o)
  {
    if(OK(o)){
      return info(o);
    }
    else{
      return info(sel);
    } 
  }
  
  //由于边框及margin影响，内层元素实际尺寸要递减，返回递减值
  //w:成立表示宽度
  function sub(o,w)
  {
    var re = 0;
  
    var pa = o.parent();
    var type = pa.attr("type");
    
    while(same(type,"tb") || same(type,"td") ){
      re += 8;
      pa = pa.parent();
      type = pa.attr("type");
    }
    
    return re;
  }
  
  //返回子节点类型
  //父节点的子节点类型需一致，要是行全是行，要是列全是列
  //返回结果：0表示无子节点，1：表示子节点为行 2：表示子节点为列
  function child(o)
  {
    var cs = o.children();
    if(cs.length == 0){
      return 0;
    }
    else{
      var type = cs.eq(0).attr("type");
      if(same(type,"tb")){
        return 1;
      }
      else if(same(type,"td")){
        return 2;
      }
    }
  }

  /*
    将布局转换为table形式
    
    child方法返回值: 
        0表示无子节点，1：表示子节点为行 2：表示子节点为列
        
    边框线绘制：
        单个table内画相邻兄弟td交界线。最外层用一个div围起来。
    
    lb是Layout_Buffer对象
    
    flag=0:普通模式。flag=1：预览模式
  */
  function convert(o,lb,flag)
  {
    var v = child(o);
    var _b = borderCheck(o);
    
    if(v == 0){
      return "";
    }
    else if(v == 1){//自己是个列(有没有右边框)

      var _w = o.attr("_w");
      if(_b.right){_w -= 1;}
 
      var t = "<table class='l_tb' cellpadding='0' style='width:"+_w+"px;border-spacing:0;table-layout:fixed;box-sizing:border-box;word-break:break-all;'><tbody>";
      
      var L = o.children().length;
      
      o.children().each(function(index){
        var ID = $(this).prop("id");
      
        var code = convert($(this),lb,flag);
        var _cd = code;
        
        if(!OK(code) && lb != null){
          _cd = lb.get(ID);
        }
        
        var CD = " code='"+(OK(code) ? "y" : "n")+"' ";
        
        var click = "";
        if(!OK(code) && OK(_click)){
          click = "onclick='parent.window."+_click+"(this.style.width,this.style.height,this.style.paddingLeft);' ";
        }
        
        var _p = "";
        var padding = "";
        var pd = $(this).attr("_p");
        if(!OK(code) && OK(pd)){
          padding = "padding:"+pd+"px;";
          _p = " _p='"+pd+"' ";
        }
        

        //对于table元素，如th、td来说，使用height属性就等效于min-height属性了
        var _h = $(this).attr("_h"); 
        
        if( index +1 == L && _b.bottom){_h -= 1;}

        if(OK(_border) && L > 1 && index +1 < L){//画td分界线
        
          var bd = "border-bottom:"+_border+" solid 1px;";
          if(same(_border,"#fff")){
            if(flag == 1){
              bd = "border-bottom:#bbb dotted 1px;";
            }
            else{
              bd = "";
            }
          }

          t = t + "<tr><td class='l_td' id='"+ID+"' _h='"+_h+"' "+_p+" valign='top' "+click+CD+" style='overflow-x:hidden;box-sizing:border-box;border-left:none;border-top:none;border-right:none;"+bd+"width:"+_w+"px;height:"+_h+"px;"+padding+"'>"+_cd+"</td></tr>";
        }
        else{
          t = t + "<tr><td class='l_td' id='"+ID+"' _h='"+_h+"' "+_p+" valign='top' "+click+CD+" style='overflow-x:hidden;box-sizing:border-box;width:"+_w+"px;height:"+_h+"px;border:none;"+padding+"'>"+_cd+"</td></tr>";
        }
      });
      
      t = t+"</tbody></table>";
      return t;
    }
    else if(v == 2){//自己是个行（有没有下边框）
      var _w = _width(o);
      if(_b.right){_w -= 1;}
      
      var _h = o.attr("_h");
      if(_b.bottom){_h -= 1;}
      
      var t = "<table class='l_tb' cellpadding='0' style='width:"+_w+"px;border-spacing:0;table-layout:fixed;box-sizing:border-box;word-break:break-all;'><tbody><tr>";
      
      var L = o.children().length;
      
      o.children().each(function(index){
      
        var ID = $(this).prop("id");
        
        var code = convert($(this),lb,flag);
        var _cd = code;
        
        if(!OK(code) && lb != null){
          _cd = lb.get(ID);
        }
        var CD = " code='"+(OK(code) ? "y" : "n")+"' ";
        
        var click = "";
        if(!OK(code) && OK(_click)){
          click = "onclick='parent.window."+_click+"(this.style.width,this.style.height,this.style.padding);' ";
        }
        
        var padding = "";
        var _p = "";
        var pd = $(this).attr("_p");
        if(!OK(code) && OK(pd)){
          padding = "padding:"+pd+"px;";
          _p = " _p='"+pd+"' ";
        }
        
        _w = $(this).attr("_w");
        if(index +1 == L && _b.right){ _w -= 1;}

        if(OK(_border) && L > 1 && index +1 < L){//画td分界线
  
          var bd = "border-right:"+_border+" solid 1px;";
          if(same(_border,"#fff")){
            if(flag == 1){
              bd = "border-right:#bbb dotted 1px;";
            }
            else{
              bd = "";
            }
          }      
        
          t = t + "<td class='l_td' id='"+ID+"' _w='"+_w+"' "+_p+" valign='top' "+click+CD+" style='overflow-x:hidden;box-sizing:border-box;border-left:none;border-top:none;border-bottom:none;"+bd+"width:"+_w+"px;height:"+_h+"px;"+padding+"'>"+_cd+"</td>";
        }
        else{
          t = t + "<td class='l_td' id='"+ID+"' _w='"+_w+"' "+_p+" valign='top' "+click+CD+" style='overflow-x:hidden;box-sizing:border-box;border:none;width:"+_w+"px;height:"+_h+"px;"+padding+"'>"+_cd+"</td>";
        }
      });
      
      t = t+"</tr></tbody></table>";
      return t;
    }
  }
  
  //获取布局代码,最外层套个div
  //lb是Layout_Buffer对象
  //flag=1，将白色(无色)边框画成虚线
  this.get = function(lb,flag)
  {
    var temp = obj.clone();
    adjust(temp);

  
    var w = "width:"+ temp.attr("_w") + "px;";
    var h = "min-height:"+temp.attr("_h") + "px;";
    
    var bd = "";
    if(OK(_border)){
      if(same(_border,"#fff")){
        if(flag == 1){bd = "border:#bbb dotted 1px;" ;}
      }
      else{
        bd = "border:"+_border+" solid 1px;";
      }
    }
    
    var code = convert(temp,lb,flag);
    
    if(code.length == 0){
      var _w = obj.attr("_w");
      var _h = obj.attr("_h");
      var CD =" code='n' ";
      
      var padding = "";
      var pd = obj.attr("_p");
      if(OK(pd)){
        padding = "padding:"+pd+"px;";
      }
      
      var click = "";
      if(OK(_click)){
        click = "onclick='parent.window."+_click+"(this.style.width,this.style.height,this.style.padding);' ";
      }
      code = "<table class='l_tb' cellpadding='0' style='border-spacing:0;table-layout:fixed;'><tbody><tr><td class='l_td' valign='top' "+click+CD+" style='box-sizing:border-box;width:"+_w+"px;height:"+_h+"px;"+padding+"'></td></tr></tbody></table>";
    }
    
    var ck = "";
    if(OK(_click)){ck = " ck='"+_click+"' ";}

    var t = "<div class='l_con' id='"+obj.prop("id")+"' _w='"+temp.attr("_w")+"' _h='"+temp.attr("_h")+"' bd='"+_border+"' "+ck+" style='"+w+h+bd+"'>"+code+"</div>";

    return t;
  }
  
  function info(O)
  {
    if(!OK(O)){return null;}
    else{
      var re = {};
      re.id = ROOT;
      re.root = same(O.prop("id"),ROOT);
      re.type = O.attr("type");
      re.child = child(O);
      
      if(re.root){
        re.width = parseInt(O.attr("_w"));
        re.height = parseInt(O.attr("_h"));
      }
      else{
        if(re.type == "tb"){
          re.width = _width(O);
          re.height = parseInt(O.attr("_h"));
        }
        else if(re.type == "td"){
          re.width = parseInt(O.attr("_w"));
          re.height = _height(O);
        }
      }

      re.padding = parseInt(O.attr("_p"));

      //剩余可用宽度或高度，相对于子容器
      if(re.child == 1){
        var hs = 0;
        O.children().each(function(){
          hs += parseInt($(this).attr("_h"));
        });
        re.hs = hs;
        re.rh = re.height - hs;
        re.rw = 0;
      }
      else if(re.child == 2){
        var ws = 0;
        O.children().each(function(){
          ws += parseInt($(this).attr("_w"));
        });
        re.ws = ws;
        re.rw = re.width - ws;
        re.rh = 0;
      }
      else{
        re.rw = re.width;
        re.rh = re.height;
      }

      //最大宽度或高度,相对于父容器
      if(re.root){
        re.mw = 2560;
        re.mh = 2880;
      }
      else{
        if(re.type == "tb"){
          var hs = 0;
          O.parent().children().each(function(){
            if(!same($(this).prop("id"),O.prop("id"))){
              hs += parseInt($(this).attr("_h"));
            }
          });
          re.mh = _height(O) - hs;
          re.mw = 0;
        }
        else if(re.type == "td"){
          var ws = 0;
          O.parent().children().each(function(){
            if(!same($(this).prop("id"),O.prop("id"))){
              ws += parseInt($(this).attr("_w"));
            }
          });
          re.mw = _width(O) - ws;
          re.mh = 0;
        }
      }

      return re;
    }
  }

  
  //height不能小于MH 
  this.addRow = function(height,id)
  {
    if(child(sel) == 2 || (same(sel.attr("type"),"tb") && !same(sel.prop("id"),ROOT))){
      return;
    }
    
    var ID = OK(id) ? id : ("td_"+randomString(8));
    

    //计算在设计器中的尺寸
    //通过缩放原理来计算尺寸
    var _h1 = _height(sel);
    var _h2 = sel.height() - 4;
    var per = _h2/_h1;
    var he = parseInt(height * per) - 5;
    var H = "height:"+he+"px;";
    //alert(sel.height());

    var o = $("<div id='"+ID+"' type='tb' _h='"+height+"' _w='0' _p='0' style='width:auto;"+H
                +"overflow:hidden;background-color:#fff;border:#888 dotted 1px;margin:3px 3px 0 3px;'></div>");

    
    o.click(function(event){
      event.stopPropagation();
      if(_lock){_lock = false;return;}
    
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = $(this);
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        onSel(info(sel));
      }
    });
    
    sel.append(o);
    sel.attr("_p","0");
    
    if(OK(dg)){dg.add(ID,2);}
    
    if(OK(onSel)){
      onSel(info(sel));
    }
    
    return ID;
  }
  
  //在被选元素前插入行
  this.insertRow = function(height)
  {
    var tg = sel.parent();
  
    if(same(sel.prop("id"),ROOT) || child(tg) == 2){
      return;
    }
    
    var ID = "td_"+randomString(8);
    
    //计算在设计器中的尺寸

    var _h1 = _height(tg);
    var _h2 = tg.height() - 4;
    var per = _h2/_h1;
    var he = parseInt(height * per) - 5;
    var H = "height:"+he+"px;";

    
    var o = $("<div id='"+ID+"' type='tb' _h='"+height+"' _w='0' _p='0' style='width:auto;"+H
                +"overflow:hidden;background-color:#fff;border:#888 dotted 1px;margin:3px;'></div>");

    
    o.click(function(event){
    
      event.stopPropagation();
      
      if(_lock){_lock = false;return;}
    
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = $(this);
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        onSel(info(sel));
      }
    });
    
    sel.before(o);
    
    if(OK(dg)){dg.add(ID,2);}
    
    if(OK(onSel)){
      onSel(info(sel));
    }
    return ID;
  }
  
  //width不能小于MW
  this.addCol = function(width,id)
  {
    if(child(sel) == 1 || same(sel.attr("type"),"td")){
      return;
    }
    
    var ID = OK(id) ? id : ("td_"+randomString(8));
  
    //设计器中的宽度
    var w1 = _width(sel);
    var w2 = sel.width() - 4;
    var per = w2/w1;
    var W = parseInt(width * per) - 5;

    
    var o = $("<div id='"+ID+"' type='td' _h='0' _w='"+width+"' _p='0'  style='width:"+
    W+"px;height:calc(100% - 8px);margin:3px 0 3px 3px;float:left;overflow:hidden;background-color:#fff;border:#888 dotted 1px;'></div>");

    o.click(function(event){
      event.stopPropagation();
      if(_lock){_lock = false;return;}
      
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = $(this);
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        onSel(info(sel));
      }
    });
    
    sel.append(o);
    sel.attr("_p","0");
    
    if(OK(dg)){dg.add(ID,1);}
    
    if(OK(onSel)){
      onSel(info(sel));
    }
    return ID;
  }
  
  //在被选元素左侧插入列
  this.insertCol = function(width)
  {
    var tg = sel.parent();
    
    if(same(sel.prop("id"),ROOT) || child(tg) == 1){
      return;
    }
    
    var ID = "td_"+randomString(8);
  
    //设计器中的宽度
    var w1 = _width(tg);
    var w2 = tg.width() - 4;
    var per = w2/w1;
    var W = parseInt(width * per) - 5;
    
    
    var o = $("<div id='"+ID+"' type='td' _h='0' _w='"+width+"' _p='0'  style='width:"+W+"px;height:calc(100% - 8px);float:left;overflow:hidden;background-color:#fff;border:#888 dotted 1px;margin:3px;'></div>");

    o.click(function(event){
      event.stopPropagation();
      if(_lock){_lock = false;return;}
      
      if(OK(sel)){
        sel.css("background-color","#fff");
        if(OK(dg)){dg.setFlag(sel.prop("id"),false);}
      }
    
      sel = $(this);
      sel.css("background-color","#E6EFFA");
      if(OK(dg)){dg.setFlag(sel.prop("id"),true);}
      
      if(OK(onSel)){
        onSel(info(sel));
      }
    });
    
    sel.before(o);
    if(OK(dg)){dg.add(ID,1);}
    
    if(OK(onSel)){
      onSel(info(sel));
    }
    return ID;
  }
  
  //递归清理drag对象
  function dgdel(o)
  {
    if(OK(dg)){dg.del(o.prop("id"));}
    
    o.children().each(function(){
      dgdel($(this));
    });
  }
  
  //移除当前选择项
  this.del = function()
  {
    if(same(sel.prop("id"),ROOT)){
      if(OK(dg)){dgdel(obj);}//dg是drag对象
      obj.empty();
    }
    else{
      if(OK(dg)){dgdel(sel);}
      sel.remove();
    }
    
    sel = null;
    if(OK(onSel)){
      onSel(info(sel));
    }
  }
  
  
  //设置当前项高度
  this.setHeight = function(h)
  {
    var o = sel;
    var pa = same(o.prop("id"),ROOT) ? o : o.parent();
    var he = h;
  
    if(same(o.attr("type"),"tb") || same(o.prop("id"),ROOT)){
    
      o.attr("_h",h+"");
      
      if(!same(o.prop("id"),ROOT)){

        var _h1 = _height(pa);
        var _h2 = pa.height() - 4;
        var per = _h2/_h1;
        he = parseInt(h * per) - 5;
      }
      
      o.height(he);
     
      if(OK(onSel)){
        onSel(info(sel));
      }
    }
  }
  
  
  //设置当前项宽度
  this.setWidth = function(w)
  {
    var o = sel;
    var pa = same(o.prop("id"),ROOT) ? o : o.parent();
    
    if(same(o.attr("type"),"td") || same(o.prop("id"),ROOT)){
      var W = w;
      
      if(!same(o.prop("id"),ROOT)){
        var w1 = _width(pa);
        var w2 = pa.width() - 4;
        var per = w2/w1;
        W = parseInt(w * per) - 5;
      }
    
      o.attr("_w",w+"");
      o.width(W);

      if(OK(onSel)){
        onSel(info(sel));
      }
    }
  }
  
  //设置当前项内边距
  this.setPadding = function(p)
  {
    var o = sel;
    
    if(child(o) == 0){
      o.attr("_p",p+"");
      
      if(OK(onSel)){
        onSel(info(sel));
      }
    }
  }
}


//获取标签属性
function getProp(source,tagName,propName)
{
  var reg = new RegExp("<"+tagName+"[^>]*"+propName+"=['\"](.+?)['\"][^>]*>","i");
  var r = reg.exec(source);
  if(r != null){
    return r[1];
  }
  else{
    return null;
  }
}

//获取某类标签内部html内容
//如果标签嵌套，无法获取内层标签内容
function getHtml(source,tagName,prop,value)
{
  var result = new Array();

  var reg = new RegExp("<"+tagName+"[^>]*"+prop+"=['\"]"+value+"[^>]*>","ig");
  var reg2 = new RegExp("</?"+tagName+"[^>]*>","ig");
  
  var r = reg.exec(source);
  
  while(r != null){
  
    var S = 1;//开始标签计数
    var E = 0;//结束标签计数
    
    var data = {};
    data.header = r[0];
    data.id = getProp(r[0],tagName,"id");
    var W = getProp(r[0],tagName,"_w");
    var H = getProp(r[0],tagName,"_h");
    data.width = OK(W) ? parseInt(W) : 0;
    data.height = OK(H) ? parseInt(H) : 0;
    data.border = getProp(r[0],tagName,"bd");
    data.click = getProp(r[0],tagName,"ck");

    var i = r.index;
    i += r[0].length;
    reg2.lastIndex = i;
    data.start = i;
    
    var r2 = reg2.exec(source);
    
    while(r2 != null){
      if(r2[0].charAt(1) == '/'){
        E++;
      }
      else{
        S++;
      }
      
      if(S == E){
        if(i == r2.index){
          data.html = null;
        }
        else{
          data.html = source.substring(i,r2.index);
          data.end = r2.index;
        }
        
        reg.lastIndex = r2.index + r2[0].length;
        break;
      }
      
      r2 = reg2.exec(source);
    }
    
    result.push(data);

    r = reg.exec(source);
  }
  
  return result;
}


/*
参数格式：标签名称=标签宽度,...
*/
function TabPanel(width,height,para)
{
  var _bw = width;
  var _bh = height;
  var _bh2 = _bh - 25;

  var onsel = null;
  var last = 0;

  var header = "<div style='height:24px;line-height:24px;font-size:14px;background-color:#f1eded;'>";
  var con = "<div style='width:"+_bw+"px;height:"+_bh2+"px;overflow:hidden;background-color:#fff;'>";
  var obj = null;
  
  if(para != undefined && para != null && para.length > 0){
    var ps = para.split(",");
    
    var ws = 0;
    
    for(var i=0;i<ps.length;++i){
      var s = ps[i].split("=");
      var w = parseInt(s[1]);
      ws += w;
      
      if(i==0){
        header += "<div class='tag' style='width:"+w+"px;height:24px;text-align:center;float:left;cursor:default;background-color:#fff;font-weight:bold;border-bottom:#fff solid 1px;'>"+s[0]+"</div>";
      }
      else{
        header += "<div class='tag' style='width:"+w+"px;height:24px;text-align:center;float:left;cursor:default;background-color:#f1eded;border-bottom:#bbb solid 1px;'>"+s[0]+"</div>";
      }
      
      header += "<div style='width:0px;height:24px;float:left;border-left:#bbb solid 1px;border-right:#fff solid 1px;border-bottom:#bbb solid 1px;'></div>";
      
      if(i==0){
        con += "<div style='width:"+_bw+"px;height:"+_bh2+"px;overflow:hidden;'></div>";
      }
      else{
        con += "<div style='display:none;width:"+_bw+"px;height:"+_bh2+"px;overflow:hidden;'></div>";
      }
    }
    
    
    header += "<div style='width:"+(_bw-ws-ps.length*2)+"px;height:24px;float:left;border-bottom:#bbb solid 1px;'></div>";

    obj = $("<div style='width:"+_bw+"px;height:"+_bh+"px;overflow:hidden;position:absolute;z-index:999;left:0;top:0;'>"+header+"</div>"+con+"</div></div>");
    
    obj.children().eq(0).children(".tag").each(function(){
      $(this).click(function(){
        var now = $(this).prevAll(".tag").length;
      
        if(last != now){
          obj.children().eq(0).children(".tag").eq(last).css("background-color","#f1eded");
          obj.children().eq(0).children(".tag").eq(last).css("border-bottom-color","#bbb");
          obj.children().eq(0).children(".tag").eq(last).css("font-weight","normal");
          $(this).css("background-color","#fff");
          $(this).css("border-bottom-color","#fff");
          $(this).css("font-weight","bold");
          obj.children().eq(1).children().eq(last).css("display","none");
          
          
          var i = obj.children().eq(0).children(".tag").eq(last).prevAll().length - 1;
          if(i>0){
            obj.children().eq(0).children().eq(i).css("border-bottom-color","#bbb");
          }
          
          last = now;
          obj.children().eq(1).children().eq(now).css("display","");
          
          i = obj.children().eq(0).children(".tag").eq(now).prevAll().length - 1;
          if(i>0){
            obj.children().eq(0).children().eq(i).css("border-bottom-color","#fff");
          }
        }
      
        if(onsel != null){
          onsel($(this).text());
        }
      });
    });
  }
  
  
  this.getObj = function()
  {
    return obj;
  }
  
  //返回指定容器(jquery对象)
  this.get = function(tag)
  {
    var index = 0;
    
    obj.children().eq(0).children(".tag").each(function(i){
      if(tag == $(this).text()){
        index = i;
      }
    });

    return obj.children().eq(1).children().eq(index);
  }
  
  //选择某个标签(容器)，不会触发事件
  this.set = function(tag)
  {
    var now = 0;
    
    obj.children().eq(0).children(".tag").each(function(i){
      if(tag == $(this).text()){
        now = i;
      }
    });
    
    if(last != now){
      obj.children().eq(0).children(".tag").eq(last).css("background-color","#f1eded");
      obj.children().eq(0).children(".tag").eq(last).css("border-bottom-color","#bbb");
      obj.children().eq(0).children(".tag").eq(last).css("font-weight","normal");
      obj.children().eq(0).children(".tag").eq(now).css("background-color","#fff");
      obj.children().eq(0).children(".tag").eq(now).css("border-bottom-color","#fff");
      obj.children().eq(0).children(".tag").eq(now).css("font-weight","bold");
      obj.children().eq(1).children().eq(last).css("display","none");
      
      
      var i = obj.children().eq(0).children(".tag").eq(last).prevAll().length - 1;
      if(i>0){
        obj.children().eq(0).children().eq(i).css("border-bottom-color","#bbb");
      }
      
      last = now;
      obj.children().eq(1).children().eq(now).css("display","");
      
      i = obj.children().eq(0).children(".tag").eq(now).prevAll().length - 1;
      if(i>0){
        obj.children().eq(0).children().eq(i).css("border-bottom-color","#fff");
      }
    }
  }
  
  //标签切换，回调函数参数：标签（容器）文本
  this.setSel = function(fun)
  {
    onsel = fun;
  }
}

/*

st:静态文本
it:输入框
bt:按钮
sp:空白间隔
示例：var tb = new ToolBar(10,10,"st宽度：=56,it=50,st高度：=56,it=50,bt获取文本=80,bt测试=60,bt测试2=60");

*/
function ToolBar(marginLeft,marginTop,para)
{
  var temp = "<table style='font-size:14px;margin-top:"+marginTop+"px;margin-left:"+marginLeft+"px;'><tbody><tr>";
  var obj = null;
  var tr = null;
  
  if(para != undefined && para != null && para.length > 0){
    var ps = para.split(",");
    for(var i=0;i<ps.length;++i){
      temp += "<td style='height:25px;'></td>";
    }
    temp += "</tr></tbody></table>";
    obj = $(temp);
    tr = obj.children("tbody").children("tr").eq(0);
    
    for(var i=0;i<ps.length;++i){
      var s = ps[i].split("=");
      var w = parseInt(s[1]);
      var type = s[0].substring(0,2);
      var text = s[0].substring(2);
      
      switch(type){
      case "bt":
      addButton(i,w,text)
      break;
      case "it":
      addInput(i,w,text);
      break;
      case "st":
      addStatic(i,w,text);
      break;
      case "sp":
      addSep(i,w);
      }
    }
  }
  
  
  var onclick = null;//参数:按钮文本
  
  this.getObj = function()
  {
    return obj;
  }
  
  function get(index)
  {
    return tr.children().eq(index).children().eq(0);
  }
  
  //设置按钮点击响应函数
  this.setClick = function(fun)
  {
    onclick = fun;
  }
  
  //设置按钮或编辑框状态
  this.enable = function(index,e)
  {
    var type = get(index).prop("type");
    
    if(same(type,"text")){
      if(e){
        get(index).removeAttr("readonly");
      }
      else{
        get(index).attr("readonly", true);
      }
    }
    else if(same(type,"button")){
      if(e){
        get(index).removeAttr("disabled");
      }
      else{
        get(index).attr("disabled", "disabled");
      }
    }
  }
  
  //设置或获取编辑框文本
  this.text = function(index,t)
  {
    if(t != undefined && t != null){
      get(index).attr("value",t)
    }
    else{
      return get(index).attr("value")
    }
  }

  function addSep(i,width)
  {
    var n = $("<div style='width:"+width+"px;height:25px;'></div>");
    tr.children().eq(i).append(n);
  }
  
  function addStatic(i,width,text)
  {
    var n = $("<div style='width:"+width+"px;height:25px;line-height:25px;text-align:right;'>"+text+"</div>");
    tr.children().eq(i).append(n);
  }
  
  function addInput(i,width,text)
  {
    var value = "";
    if(text != undefined && text != null && text.length > 0){
      value = "value='"+text+"'";
    }
    var n = $("<input style='width:"+width+"px;' type='text' "+value+" maxlength='4' />");
    tr.children().eq(i).append(n);
  }
  
  function addButton(i,width,text)
  {
    var n = $("<input type='button' value='"+text+"' style='width:"+width+"px;height:25px;line-height:20px;' />");
    n.click(function(){
      if(onclick != null){
        onclick($(this).attr("value"));
      }
    });
    tr.children().eq(i).append(n);
  }
}

//让div的边可托拽
function Drag(con)
{
  var delay = 200;//鼠标停止时响应hover事件，该值决定了触发事件的延时
  var CON = con;//托拽对象父容器，用于光标设定


  var x = 0;
  var y = 0;
  
  var last = {"x":0,"y":0};
  
  var divs = new Array();//div对象集合
  var types = new Array();//指定哪条边可以托拽. type=1:可向右边托拽,type=2:可向下边托拽,type=3:可向右边和下边托拽。
  var ons = new Array();//光标是否在边框上
  var flags = new Array();//是否允许托拽
  
  
  var onHover = null;
  var onStart = null;
  var onDrag = null;
  var onEnd = null;
  
  //托拽数据
  var startDrag = false;
  var sid = null;
  var sdiv = null;//开始托拽时的div
  var son = 0;//表示托拽div哪条边
  var sx = 0;//div x向绝对位置
  var sy = 0;//div y向绝对位置
  
  var dx = 0;//开始托拽时光标x位置
  var dy = 0;//开始托拽时光标y位置
  var dw = 0;//开始托拽时div宽
  var dh = 0;//开始托拽时div高

  $('body').mousemove(function(e){
    x = e.pageX;
    y = e.pageY;
    
    if(last.x == 0 && last.y == 0){
      last.x = x;
      last.y = y;
    }

    var on = false;

    for(var i=0;i<divs.length;++i){
      var div = $("#"+divs[i]);
      
      
      var _x = div.offset().left;
      var _y = div.offset().top;
      
      var w = div.width();
      var h = div.height();
      
      
      if(y >= _y && y <= _y+h && x >= (_x+w-2) && x <= _x + w+4){
        if(flags[i] && (types[i] == 1 || types[i] == 3)){
          ons[i] = 1;
          on = true;
          break;
        }
      }
      
      if(flags[i] && x >= _x && x <= _x+w && y >= (_y + h - 2) && y <= _y + h+4){
        if(flags[i] && (types[i] == 2 || types[i] == 3)){
          ons[i] = 2;
          on = true;
          break;
        }
      }
    }
    
    if(startDrag){
      if(son == 1){
        if(x > sx){
          if(onDrag != null){
            if(onDrag(sdiv,1,dw,x-dx)){
              sdiv.width(dw + x-dx );
            }
          }
          else{sdiv.width(dh + y - dy);}
        }
      }
      else if(son == 2){
        if(y > sy){
          if(onDrag != null){
            if(onDrag(sdiv,2,dh,y - dy)){
              sdiv.height(dh + y - dy);
            }
          }
          else{
            sdiv.height(dh + y - dy);
          }
        }
      }
    }
    else{
      if(!on){
        for(var i=0;i<ons.length;++i){
          var div = $("#"+divs[i]);
          
          if(ons[i] == 1){
            div.css("border-right-color","#bbb");
            ons[i] = 0;
            break;
          }
          else if(ons[i] == 2){
            div.css("border-bottom-color","#bbb");
            ons[i] = 0;
            break;
          }
        }
        $("#"+CON).css("cursor","default");
      }
      else{
        for(var i=0;i<ons.length;++i){
          if(ons[i] == 1){
            $("#"+divs[i]).css("border-right-color","#f00");
            $("#"+CON).css("cursor","ew-resize");
            break;
          }
          else if(ons[i] == 2){
            $("#"+divs[i]).css("border-bottom-color","#f00");
            $("#"+CON).css("cursor","ns-resize");
            break;
          }
        }
      }
    }
  });


  $("body").mousedown(function(){
      for(var i=0;i<ons.length;++i){
        if(ons[i] > 0){
          sid = divs[i];
          sdiv = $("#"+divs[i]);
          son = ons[i];
          sx = sdiv.offset().left;
          sy = sdiv.offset().top;
          startDrag = true;
          dx = x;
          dy = y;
          dw = sdiv.width();
          dh = sdiv.height();
          if(OK(onStart)){
            onStart(sid,son);
          }
          return;
        }
      }
      startDrag = false;
  });
  
  $("body").mouseup(function(){
    if(startDrag){
      startDrag = false;
      if(OK(onEnd)){
        onEnd(sid,son);
      }
    }
  });
  
  //div是jquery对象
  //type=1:可向右边托拽,type=2:可向下边托拽,type=3:可向右边和下边托拽。
  this.add = function(id,type)
  {
    divs.push(id);
    types.push(type);
    ons.push(0);
    flags.push(false);
  }
  
  this.del = function(id)
  {
    var j = -1;
    
    for(var i=0;i<divs.length;++i){
      if(divs[i] == id){
        j=i;
        break;
      }
    }
    
    var s = divs.length;
    
    if(j >= 0){
      divs.splice(j,1);
      types.splice(j,1);
      ons.splice(j,1);
      flags.splice(j,1);
    }
  }
  
  function _clear()
  {
    divs = new Array();
    types = new Array();
    ons = new Array();
    flags = new Array();
  }
  
  this.clear = function()
  {
    _clear();
  }
  
  
  //fun(x,y)
  this.setHover = function(fun)
  {
    onHover = fun;
  }
  

  //start(id,border)
  //drag(id,border,size,offset) border=1表示宽度，border=2表示高度，初始宽/高度，增/减量. 返回true表示接受尺寸改变，否则尺寸不改变
  //end(id,border)
  this.setDrag = function(start,drag,end)
  {
    onStart = start;
    onDrag = drag;
    onEnd = end;
  }
  
  //id值所指div是否可以托拽
  this.setFlag = function(id,b)
  {
    for(var i=0;i<divs.length;++i){
      if(divs[i] == id){
        flags[i] = b;
        break;
      }
    }
  }
}

//颜色选择控件
function Colors(marginLeft,marginTop,onSelect)
{
  var obj = $("<table style='font-size:14px;margin-top:"+marginTop+"px;margin-left:"+marginLeft+"px;'><tbody><tr><td><div style='width:56px;text-align:right;'>边框：</div></td><td><div style='width:110px;float:left;'>"+
  "<div id='c1' color='#fff' style='width:20px;height:20px;border:#000 solid 1px;float:left;margin:1px;background-color:#fff;'></div>"+
  "<div id='c2' color='#000' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#000;'></div>"+
  "<div id='c3' color='#999' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#999;'></div>"+
  "<div id='c4' color='#96C2F1' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#96C2F1;'></div>"+
  "<div id='c5' color='#92B0DD' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#92B0DD;'></div>"+
  "<div id='c6' color='#ed9121' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#ed9121;'></div>"+
  "<div id='c7' color='#f00' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#f00;'></div>"+
  "<div id='c8' color='#D2B48C' style='width:20px;height:20px;border:#fff solid 1px;float:left;margin:1px;background-color:#D2B48C;'></div>"+
  +"</div></td></tr></tbody></table>");
  
  var td = obj.children("tbody").children("tr").eq(0).children().eq(1);
  
  
  this.getObj = function(){
    return obj;
  }
  
  var sel = "c1";
  var C = "#fff";
  var onSel = onSelect;
  
  td.children().eq(0).children().each(function(){
    $(this).click(function(){
      if(sel != null){
        obj.find("div#"+sel).css("border-color","#fff");
      }
      
      sel = $(this).prop("id");
      $(this).css("border-color","#000");
      C = $(this).attr("color");
      
      if(OK(onSel)){
        onSel(C);
      }
    });
  });
  
  this.get = function()
  {
    return C;
  }
  
  this.set = function(color)
  {
    td.children().eq(0).children().each(function(){
    
        if(same($(this).attr("color"),color)){
          if(sel != null){
            obj.find("div#"+sel).css("border-color","#fff");
          }
          
          sel = $(this).prop("id");
          $(this).css("border-color","#000");
          C = $(this).attr("color");
          return true;
        }
    });
  }
}

//生成随机数
function randomString(length){
  var x="qwertyuioplkjhgfdsazxcvbnm";
  var tmp="";
  for(var i=0;i<length;i++){
    tmp += x.charAt(Math.ceil(Math.random()*100000000)%x.length);
  }
  return tmp;
}

//判断对象是否为空
function OK(obj)
{
  if(obj === 0 && obj == 0){return true;}

  return ((obj == undefined || obj == null || obj == "" ) ? false : true);
}

//去掉两端不可见字符
function trim(str)
{
  return str.replace(/(^\s*)|(\s*$)/g, "");
}

//比较两个字符串是否相同，不区分大小写
function same(str1,str2)
{
  if(str1 == null || str2 == null){
    return false;
  }

  if(trim(str1.toLowerCase()) == trim(str2.toLowerCase())){
    return true;
  }
  else{return false;}
}

function getBodyWidth()
{
  return document.body.clientWidth;
}

function getBodyHeight()
{
  return document.documentElement.clientHeight;
}

/*

字符串替换
flag：包含s表示忽略不可见字符，包含c表地忽略大小写

*/
function strReplace(flag)
{
  var f = (flag != undefined && flag != null) ? flag : "";
  var FS = f.indexOf("s") >= 0 ? true : false;//忽略不可见字符
  var FC = f.indexOf("c") >= 0 ? true : false;//忽略大小写
  
  //过滤掉字符串中的不可见字符
  function charFilter(str){
      var strArr = new Array();

      for(var i = 0;i<str.length;i++){
          if(str.charCodeAt(i) > 32){
            strArr.push(str.charAt(i));
          }
       }
      return strArr.join('');
  }
  
  //替换第一个符合条件项
  this.replace = function(source,find,rep)
  {
    var _s = FC ? source.toLowerCase() : source;
    var _f = FC ? find.toLowerCase() : find;
    
    if(f.indexOf("s") >= 0){
      _f = charFilter(_f);
    }
    
    var start = 0;
    var end = 0;
    var count = 0;
    var find = true;
    
    for(var i=0;i<_s.length;++i){
      
      start = i;
      offset = -1;
      find = true;
      count = 0;
 
      while(count < _f.length){
        offset ++;
        
        if(i + offset == _s.length){find = false;break;}
      
        if(FS && (_s.charCodeAt(i+offset) < 33)){//33以下为不可见字符
          continue;
        }
        
        if(_s.charCodeAt(i+offset) != _f.charCodeAt(count)){
          find = false;
          break;
        }

        count ++;
        end = start + offset;
      }
      
      if(find){
        break;
      }
    }
    
    if(find){
      return (source.substring(0,start) + rep + source.substring(end+1));
    }
    else{
      return source;
    }
  }
}
/*
function debug()
{
  var bw = document.body.clientWidth;
  var bh =document.documentElement.clientHeight; 

  var temp = "<div style='position:absolute;z-index:1000;width:"+bw+"px;height:"+bh+"px;left:0;top:0;overflow-y:scroll;background-color:#f5f5f5;'>";

  for(var i=0; i<arguments.length; i++){
     temp += "<textarea style='width:1024px;height:200px;margin:10px;'>"+arguments[i]+"</textarea>";
  }

  temp += "<div id='close' style='width:100px;height:30px;margin-top:10px;margin-left:400px;background-color:#f00;'>关闭</div></div>";
  

  var obj = $(temp);  
  $("body").append(obj);

  obj.find("#close").click(function(){
    obj.remove();
  });
}*/